package com.lauor.smpedr.spring.session;

import com.lauor.smpedr.session.SqlSession;
import com.lauor.smpedr.session.SqlSessionFactory;
import com.lauor.smpedr.spring.utils.SpringSqlSessionUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * spring sql session代理,接入spring事务管理
 */
public class SpringManagedSqlSessionProxy implements InvocationHandler {

    private SqlSessionFactory sqlSessionFactory;

    public SpringManagedSqlSessionProxy(SqlSessionFactory SqlSessionFactory) {
        this.sqlSessionFactory = SqlSessionFactory;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        SqlSession sqlSession = SpringSqlSessionUtil.getSqlSession(this.sqlSessionFactory);

        try {
            Object rs = method.invoke(sqlSession, args);
            //没有纳入spring事务中，直接提交
            if ( !SpringSqlSessionUtil.isSqlSessionTransactional(sqlSession, this.sqlSessionFactory) ){
                sqlSession.commit();
            }
            return rs;
        } catch (Throwable throwable){
            if (throwable instanceof InvocationTargetException){
                throw ((InvocationTargetException) throwable).getTargetException();
            }
            throw throwable;
        } finally {
            if (sqlSession != null){
                SpringSqlSessionUtil.closeSqlSession(sqlSession, this.sqlSessionFactory);
            }
        }
    }
}
